package xin.nick.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.context.support.SecurityWebApplicationContextUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import xin.nick.common.annotation.AopLog;
import xin.nick.common.entity.ResultCode;
import xin.nick.common.util.MyAssert;
import xin.nick.common.util.SecurityUtil;
import xin.nick.converter.SystemUserConverter;
import xin.nick.domain.dto.SystemUserAddDTO;
import xin.nick.domain.dto.SystemUserEditDTO;
import xin.nick.domain.vo.SystemUserDetailVO;
import xin.nick.entity.SystemUser;
import xin.nick.manager.SystemUserManager;
import xin.nick.mapper.SystemUserMapper;
import xin.nick.service.ISystemUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author Nick
 * @since 2022-07-27
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class SystemUserServiceImpl extends ServiceImpl<SystemUserMapper, SystemUser> implements ISystemUserService {

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    private SystemUserManager systemUserManager;

    @Override
    public SystemUser addUser(SystemUserAddDTO systemUserAddDTO) {

        SystemUser systemUser = SystemUserConverter.INSTANCE.toSystemUser(systemUserAddDTO);
        checkAccount(systemUser);
        systemUser.setPassword(bCryptPasswordEncoder.encode(systemUser.getPassword()));
        save(systemUser);
        return systemUser;
    }

    @Override
    public SystemUser editUser(SystemUserEditDTO systemUserEditDTO) {

        SystemUser systemUser = SystemUserConverter.INSTANCE.toSystemUser(systemUserEditDTO);
        checkAccount(systemUser);
        String userPassword = systemUser.getPassword();
        if (StringUtils.hasLength(userPassword)) {
            userPassword = bCryptPasswordEncoder.encode(systemUser.getPassword());
            systemUser.setPassword(userPassword);
        }
        updateById(systemUser);
        return systemUser;
    }

    @Override
    public void delete(Long userId) {
        checkDeleteUser(userId);
        removeById(userId);
    }

    @Override
    public void deleteByIdList(List<Long> userIdList) {
        if (CollectionUtils.isEmpty(userIdList)) {
            return;
        }
        for (Long userId : userIdList) {
            checkDeleteUser(userId);
        }

        removeBatchByIds(userIdList);
    }

    /**
     * 检查被删除的用户的状态可以删除吗
     * @param userId
     */
    private void checkDeleteUser(Long userId) {
        Long rootId = systemUserManager.getRootId();
        MyAssert.isTrue(!Objects.equals(rootId, userId), "不可删除超级管理员");

        Long currentUserId = SecurityUtil.getCurrentUserId();
        MyAssert.isTrue(!Objects.equals(currentUserId, userId), "不可删除自己");

    }

    /**
     * 检查用户账号是否有重复
     * @param systemUser
     */
    private void checkAccount(SystemUser systemUser) {
        if (Objects.isNull(systemUser)) {
            return;
        }
        String account = systemUser.getAccount();
        if (!StringUtils.hasLength(account)) {
            return;
        }
        LambdaQueryWrapper<SystemUser> systemUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
        systemUserLambdaQueryWrapper.eq(SystemUser::getAccount, account).last("limit 1");
        SystemUser one = getOne(systemUserLambdaQueryWrapper);
        if (Objects.nonNull(one)) {
            // 如果是更新用户的话,再判断一下 userId
            if (Objects.equals(systemUser.getUserId(), one.getUserId())) {
                return;
            }
            // 存在用户且不是当前修改的用户,则抛出错误
            MyAssert.throwException("已存在相同的 account");
        }

    }

}
